package notify

import (
	"fmt"
	"net/smtp"
	"strings"
	"time"

	"github.com/astaxie/beego"
	"github.com/astaxie/beego/logs"
)

//邮件
type PEmail struct {
	Subject string //主题
	Body    string //邮件内容
	To      string //邮件发送给谁
	Format  string //解析格式
	Config  *PEmailConfig
}

type PEmailConfig struct {
	Host     string
	Port     string //端口
	From     string //谁发送的
	User     string //用户名
	Password string //授权码
}

var (
	mailChan chan *PEmail
	config   *PEmailConfig
)

func init() {
	//加载缓冲区的大小
	poolSize, _ := beego.AppConfig.Int("email.pool")
	host := beego.AppConfig.String("email.host")
	port := beego.AppConfig.String("email.port")
	from := beego.AppConfig.String("email.from")
	user := beego.AppConfig.String("email.user")
	password := beego.AppConfig.String("email.password")

	//初始化邮件配置文件对象
	config = &PEmailConfig{
		Host:     host,
		Port:     port,
		From:     from,
		User:     user,
		Password: password,
	}

	mailChan = make(chan *PEmail, poolSize)
	go func() {
		for {
			select {
			case m, ok := <-mailChan:
				if !ok {
					return
				}
				if err := m.SendToEmail(); err != nil {
					logs.Error("SendMail: ", err.Error())
				}
			}
		}
	}()
}

func (pe *PEmail) SendToEmail() error {
	auth := smtp.PlainAuth("", pe.Config.User, pe.Config.Password, pe.Config.Host)
	sendTo := strings.Split(pe.To, ";")

	contentType := GetContentTypeString(pe.Format)

	msg := []byte("To:" + pe.To + "\r\nFrom: " + pe.Config.User +
		"\r\nSubject: " + pe.Subject + "\r\n" + contentType + "\r\n\r\n" + pe.Body)

	var err error
	if pe.Config.Port == "25" {
		err = smtp.SendMail(pe.Config.Host+":"+pe.Config.Port, auth, pe.Config.User, sendTo, msg)
	} else {
		err = fmt.Errorf("%s", "port not supported!")
	}
	return err
}

//返回邮件的类型
func GetContentTypeString(format string) string {
	var contentType string
	if format == "" {
		contentType = "Content-Type: text/plain" + "; charset=UTF-8"
	} else {
		contentType = "Content-Type: text/" + format + "; charset=UTF-8"
	}
	return contentType
}

func SendToChan(to, subject, body, mailtype string) bool {
	email := &PEmail{
		Config:  config,
		Body:    body,
		Subject: subject,
		Format:  mailtype,
		To:      to,
	}
	select {
	case mailChan <- email:
		return true
	//超时处理
	case <-time.After(time.Second * 3):
		return false
	}
}
